<?php
abstract class Observer {

    private $_listeners = array();

    public function addListener( $event, $callback ) {
        if ( in_array( $event, $this->_listeners ) ) {
            throw new Observer_Exception(_("This object not provide this event"));
        } 

        $this->_listeners[$event][] = $callback;

        return $this;
    }

    protected function hasEvent( $event ) {
        return in_array( $event, $this->_listeners );
    }

    public function removeListeners( $event ) {
        if ( $this->hasEvent( $event ) ) {
            $this->_listeners[$event] = null;
        }

        return $this;
    }

    public function fireEvent( $event, array $params = array() ) {
        if ( !$this->hasEvent( $event ) ) {
            throw new Observer_Exception( _("This object not provide this event") );
        }

        foreach ( $this->_listeners[$event] as $listener ) {
            if ( gettype($listener) == "array" || gettype($listener) == "string" ) {
                call_user_func( $listener, $params );
            } else {
                $listener($params);
            }
        }

        return $this;
    }

    public function provideEvents( array $events ) {
        foreach( $events as $event ) {
            if ( !$this->hasEvent($event) ) {
                $this->_listeners[$event] = array();
            }
        }

        return $this;
    }
}